package com.kaizeli.website.service.impl;

import com.kaizeli.website.mapper.ProjectBasicInfoMapper;
import com.kaizeli.website.mapper.ProjectAcceptanceMapper;
import com.kaizeli.website.mapper.CustomerMapper;
import com.kaizeli.website.mapper.CompanyMapper;
import com.kaizeli.website.mapper.EmployeeMapper;
import com.kaizeli.website.pojo.entity.ProjectBasicInfoDO;
import com.kaizeli.website.pojo.entity.ProjectAcceptance;
import com.kaizeli.website.pojo.entity.CustomerDO;
import com.kaizeli.website.pojo.entity.CompanyDO;
import com.kaizeli.website.pojo.model.EmployeeDO;
import com.kaizeli.website.pojo.vo.ProjectCardVO;
import com.kaizeli.website.pojo.vo.ProjectBasicInfoVO;
import com.kaizeli.website.pojo.dto.ProjectAcceptanceDTO;
import com.kaizeli.website.pojo.dto.AcceptanceMemberDTO;
import com.kaizeli.website.service.ProjectCardService;
import com.kaizeli.website.service.ProjectBasicInfoService;
import com.kaizeli.website.service.AcceptanceMemberService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 项目卡片服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ProjectCardServiceImpl implements ProjectCardService {
    
    private final ProjectBasicInfoMapper projectBasicInfoMapper;
    private final ProjectAcceptanceMapper projectAcceptanceMapper;
    private final ProjectBasicInfoService projectBasicInfoService;
    private final AcceptanceMemberService acceptanceMemberService;
    private final CustomerMapper customerMapper;
    private final CompanyMapper companyMapper;
    private final EmployeeMapper employeeMapper;
    
    @Override
    public List<ProjectCardVO> getProjectCards() {
        log.info("获取项目卡片列表");
        
        // 1. 获取所有项目基础信息
        List<ProjectBasicInfoDO> projects = projectBasicInfoMapper.selectList(null);
        
        // 2. 按项目编号分组
        Map<String, List<ProjectBasicInfoDO>> projectGroups = projects.stream()
                .collect(Collectors.groupingBy(ProjectBasicInfoDO::getProjectCode));
        
        // 3. 为每个项目编号组创建项目卡片
        return projectGroups.entrySet().stream()
                .map(entry -> createProjectCard(entry.getKey(), entry.getValue()))
                .collect(Collectors.toList());
    }
    
    @Override
    public List<ProjectCardVO> getProjectCardsByStatus(String status) {
        log.info("根据状态获取项目卡片列表，状态：{}", status);
        
        // 1. 获取所有项目基础信息
        List<ProjectBasicInfoDO> projects = projectBasicInfoMapper.selectList(null);
        
        // 2. 按项目编号分组
        Map<String, List<ProjectBasicInfoDO>> projectGroups = projects.stream()
                .collect(Collectors.groupingBy(ProjectBasicInfoDO::getProjectCode));
        
        // 3. 为每个项目编号组创建项目卡片并过滤状态
        return projectGroups.entrySet().stream()
                .map(entry -> createProjectCard(entry.getKey(), entry.getValue()))
                .filter(card -> status.equals(card.getProjectStatus()))
                .collect(Collectors.toList());
    }
    
    @Override
    public List<ProjectCardVO> getProjectCardsByCustomer(Long customerId) {
        log.info("根据客户ID获取项目卡片列表，客户ID：{}", customerId);
        
        // 1. 获取指定客户的项目基础信息
        List<ProjectBasicInfoDO> projects = projectBasicInfoMapper.selectList(
                new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<ProjectBasicInfoDO>()
                        .eq("customer_id", customerId)
        );
        
        // 2. 按项目编号分组
        Map<String, List<ProjectBasicInfoDO>> projectGroups = projects.stream()
                .collect(Collectors.groupingBy(ProjectBasicInfoDO::getProjectCode));
        
        // 3. 为每个项目编号组创建项目卡片
        return projectGroups.entrySet().stream()
                .map(entry -> createProjectCard(entry.getKey(), entry.getValue()))
                .collect(Collectors.toList());
    }
    
    @Override
    public List<ProjectCardVO> getProjectCardsByContractCompany(Long contractCompanyId) {
        log.info("根据签约公司ID获取项目卡片列表，签约公司ID：{}", contractCompanyId);
        
        // 1. 获取指定签约公司的项目基础信息
        List<ProjectBasicInfoDO> projects = projectBasicInfoMapper.selectList(
                new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<ProjectBasicInfoDO>()
                        .eq("contract_company_id", contractCompanyId)
        );
        
        // 2. 按项目编号分组
        Map<String, List<ProjectBasicInfoDO>> projectGroups = projects.stream()
                .collect(Collectors.groupingBy(ProjectBasicInfoDO::getProjectCode));
        
        // 3. 为每个项目编号组创建项目卡片
        return projectGroups.entrySet().stream()
                .map(entry -> createProjectCard(entry.getKey(), entry.getValue()))
                .collect(Collectors.toList());
    }
    
    @Override
    public List<ProjectBasicInfoVO> getSubProjectsByProjectCode(String projectCode) {
        log.info("根据项目编号获取子项目列表，项目编号：{}", projectCode);
        
        // 根据项目编号查询所有子项目
        List<ProjectBasicInfoDO> subProjects = projectBasicInfoMapper.selectList(
                new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<ProjectBasicInfoDO>()
                        .eq("project_code", projectCode)
        );
        
        // 转换为VO并填充关联信息
        return subProjects.stream()
                .map(this::convertToVOWithNames)
                .collect(Collectors.toList());
    }
    
    @Override
    public List<ProjectAcceptanceDTO> getAcceptancesByProjectCode(String projectCode) {
        log.info("根据项目编号获取验收单列表，项目编号：{}", projectCode);
        
        // 使用ProjectAcceptanceMapper的selectByProjectCode方法
        List<ProjectAcceptanceDTO> acceptances = projectAcceptanceMapper.selectByProjectCode(projectCode);
        
        // 过滤掉已作废和作废审批中的验收单
        acceptances = acceptances.stream()
                .filter(acceptance -> acceptance != null && 
                       !"已作废".equals(acceptance.getStatus()) && 
                       !"作废审批中".equals(acceptance.getStatus()))
                .collect(java.util.stream.Collectors.toList());
        
        // 为每个验收单加载成员数据（过滤掉已作废和作废审批中的成员）
        if (acceptances != null) {
            for (ProjectAcceptanceDTO acceptance : acceptances) {
                if (acceptance.getId() != null) {
                    List<AcceptanceMemberDTO> members = acceptanceMemberService.getMembersByAcceptanceId(acceptance.getId()).getData();
                    // 过滤掉已作废和作废审批中的验收成员
                    if (members != null) {
                        members = members.stream()
                                .filter(member -> member != null && 
                                       !"已作废".equals(member.getStatus()) && 
                                       !"作废审批中".equals(member.getStatus()))
                                .collect(java.util.stream.Collectors.toList());
                    }
                    acceptance.setMembers(members);
                }
            }
        }
        
        return acceptances;
    }
    
    @Override
    public List<AcceptanceMemberDTO> getAcceptanceMembers(Long acceptanceId) {
        log.info("根据验收单ID获取验收成员列表，验收单ID：{}", acceptanceId);
        
        // 使用AcceptanceMemberService获取验收成员
        return acceptanceMemberService.getMembersByAcceptanceId(acceptanceId).getData();
    }
    
    @Override
    public List<ProjectBasicInfoVO> getSubcontractProjectsByProjectCode(String projectCode) {
        log.info("根据项目编号获取分包项目列表，项目编号：{}", projectCode);
        
        // 根据项目编号查询分包项目（project_type = '3'）
        List<ProjectBasicInfoDO> subcontractProjects = projectBasicInfoMapper.selectList(
                new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<ProjectBasicInfoDO>()
                        .eq("project_code", projectCode)
                        .eq("project_type", "3")
        );
        
        // 转换为VO并填充关联信息
        return subcontractProjects.stream()
                .map(this::convertToVOWithNames)
                .collect(Collectors.toList());
    }
    
    /**
     * 创建项目卡片
     * 
     * @param projectCode 项目编号
     * @param projects 同一项目编号下的所有项目
     * @return 项目卡片
     */
    private ProjectCardVO createProjectCard(String projectCode, List<ProjectBasicInfoDO> projects) {
        if (projects.isEmpty()) {
            return null;
        }
        
        // 使用第一个项目作为基础信息（同一项目编号的项目基本信息应该相同）
        ProjectBasicInfoDO baseProject = projects.get(0);
        
        // 统计验收单信息
        Map<String, Integer> acceptanceStats = getAcceptanceStatsByProjectCode(projectCode);
        
        // 创建项目卡片
        ProjectCardVO card = new ProjectCardVO();
        card.setProjectCode(projectCode);
        card.setProjectName(baseProject.getProjectName());
        card.setTotalTasks(acceptanceStats.get("total"));
        card.setCompletedTasks(acceptanceStats.get("completed"));
        card.setPendingTasks(acceptanceStats.get("pending"));
        card.setProjectStatus(calculateProjectStatus(acceptanceStats));
        card.setStartDate(baseProject.getStartDate());
        card.setEndDate(baseProject.getEndDate());
        card.setProjectType(baseProject.getProjectType());
        card.setProjectTypeName(getProjectTypeName(baseProject.getProjectType()));
        card.setManagerId(baseProject.getManagerId());
        card.setCustomerId(baseProject.getCustomerId());
        card.setContractCompanyId(baseProject.getContractCompanyId());
        
        return card;
    }
    
    /**
     * 根据项目编号统计验收单信息
     * 
     * @param projectCode 项目编号
     * @return 统计信息Map
     */
    private Map<String, Integer> getAcceptanceStatsByProjectCode(String projectCode) {
        // 查询该项目编号下的所有验收单，排除已作废和作废审批中的状态
        List<ProjectAcceptance> acceptances = 
                projectAcceptanceMapper.selectList(
                        new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<ProjectAcceptance>()
                                .eq("project_code", projectCode)
                                .notIn("status", java.util.Arrays.asList("已作废", "作废审批中"))
                );
        
        int total = acceptances.size();
        int completed = (int) acceptances.stream()
                .filter(acceptance -> "已验收".equals(acceptance.getStatus()))
                .count();
        int pending = total - completed;
        
        Map<String, Integer> stats = new java.util.HashMap<>();
        stats.put("total", total);
        stats.put("completed", completed);
        stats.put("pending", pending);
        
        return stats;
    }
    
    /**
     * 计算项目状态
     * 当所有验收单都验收完成时，项目状态为"已验收"，否则为"进行中"
     * 
     * @param stats 验收单统计信息
     * @return 项目状态
     */
    private String calculateProjectStatus(Map<String, Integer> stats) {
        int total = stats.get("total");
        int completed = stats.get("completed");
        
        if (total == 0) {
            return "未开始";
        } else if (completed == total) {
            return "已验收";
        } else {
            return "进行中";
        }
    }
    
    /**
     * 根据项目类型字符串获取类型名称
     */
    private String getProjectTypeName(String projectType) {
        if (projectType == null || projectType.isEmpty()) {
            return null;
        }
        
        switch (projectType.toLowerCase()) {
            case "manpower":
            case "1":
                return "人力项目";
            case "turnkey":
            case "2":
                return "整包项目";
            case "subcontract":
            case "3":
                return "分包项目";
            default:
                return projectType; // 如果不知道的类型，直接返回原值
        }
    }
    
    /**
     * 转换为ProjectBasicInfoVO并填充关联名称
     */
    private ProjectBasicInfoVO convertToVOWithNames(ProjectBasicInfoDO projectDO) {
        if (projectDO == null) {
            return null;
        }
        
        ProjectBasicInfoVO vo = new ProjectBasicInfoVO();
        vo.setId(projectDO.getId());
        vo.setProjectCode(projectDO.getProjectCode());
        vo.setProjectName(projectDO.getProjectName());
        vo.setProjectSubname(projectDO.getProjectSubname());
        vo.setStartDate(projectDO.getStartDate());
        vo.setEndDate(projectDO.getEndDate());
        vo.setProjectBudget(projectDO.getProjectBudget());
        vo.setEstimatedCost(projectDO.getEstimatedCost());
        vo.setProjectType(projectDO.getProjectType());
        vo.setProjectTypeName(getProjectTypeName(projectDO.getProjectType()));
        vo.setCustomerId(projectDO.getCustomerId());
        vo.setContractCompanyId(projectDO.getContractCompanyId());
        vo.setManagerId(projectDO.getManagerId());
        vo.setDirectorId(projectDO.getDirectorId());
        vo.setApprovalTemplateId(projectDO.getApprovalTemplateId());
        vo.setDescription(projectDO.getDescription());
        
        // 处理状态：将"in_progress"转换为"未验收"
        String status = projectDO.getStatus();
        if ("in_progress".equals(status)) {
            vo.setStatus("未验收");
        } else {
            vo.setStatus(status);
        }
        
        vo.setCreatedAt(projectDO.getCreatedAt());
        vo.setUpdatedAt(projectDO.getUpdatedAt());
        vo.setCreatedBy(projectDO.getCreatedBy());
        
        // 填充客户名称
        if (projectDO.getCustomerId() != null) {
            try {
                CustomerDO customer = customerMapper.selectById(projectDO.getCustomerId());
                vo.setCustomerName(customer != null ? customer.getName() : "未分配");
            } catch (Exception e) {
                log.error("获取客户信息失败, customerId: {}", projectDO.getCustomerId(), e);
                vo.setCustomerName("未分配");
            }
        } else {
            vo.setCustomerName("未分配");
        }
        
        // 填充签约公司名称
        if (projectDO.getContractCompanyId() != null) {
            try {
                CompanyDO company = companyMapper.selectById(projectDO.getContractCompanyId());
                vo.setContractCompanyName(company != null ? company.getName() : "未分配");
            } catch (Exception e) {
                log.error("获取公司信息失败, companyId: {}", projectDO.getContractCompanyId(), e);
                vo.setContractCompanyName("未分配");
            }
        } else {
            vo.setContractCompanyName("未分配");
        }
        
        // 填充项目经理名称
        if (projectDO.getManagerId() != null) {
            try {
                EmployeeDO manager = employeeMapper.selectById(projectDO.getManagerId());
                vo.setManagerName(manager != null ? manager.getName() : "未分配");
            } catch (Exception e) {
                log.error("获取项目经理信息失败, managerId: {}", projectDO.getManagerId(), e);
                vo.setManagerName("未分配");
            }
        } else {
            vo.setManagerName("未分配");
        }
        
        // 填充项目总监名称
        if (projectDO.getDirectorId() != null) {
            try {
                EmployeeDO director = employeeMapper.selectById(projectDO.getDirectorId());
                vo.setDirectorName(director != null ? director.getName() : "未分配");
            } catch (Exception e) {
                log.error("获取项目总监信息失败, directorId: {}", projectDO.getDirectorId(), e);
                vo.setDirectorName("未分配");
            }
        } else {
            vo.setDirectorName("未分配");
        }
        
        return vo;
    }
    
    /**
     * 转换为ProjectBasicInfoVO
     */
    private ProjectBasicInfoVO convertToVO(ProjectBasicInfoDO projectDO) {
        if (projectDO == null) {
            return null;
        }
        
        ProjectBasicInfoVO vo = new ProjectBasicInfoVO();
        vo.setId(projectDO.getId());
        vo.setProjectCode(projectDO.getProjectCode());
        vo.setProjectName(projectDO.getProjectName());
        vo.setProjectSubname(projectDO.getProjectSubname());
        vo.setStartDate(projectDO.getStartDate());
        vo.setEndDate(projectDO.getEndDate());
        vo.setProjectBudget(projectDO.getProjectBudget());
        vo.setEstimatedCost(projectDO.getEstimatedCost());
        vo.setProjectType(projectDO.getProjectType());
        vo.setProjectTypeName(getProjectTypeName(projectDO.getProjectType()));
        vo.setCustomerId(projectDO.getCustomerId());
        vo.setContractCompanyId(projectDO.getContractCompanyId());
        vo.setManagerId(projectDO.getManagerId());
        vo.setDirectorId(projectDO.getDirectorId());
        vo.setApprovalTemplateId(projectDO.getApprovalTemplateId());
        vo.setDescription(projectDO.getDescription());
        vo.setStatus(projectDO.getStatus());
        vo.setCreatedAt(projectDO.getCreatedAt());
        vo.setUpdatedAt(projectDO.getUpdatedAt());
        vo.setCreatedBy(projectDO.getCreatedBy());
        return vo;
    }
}